﻿/*
 * Copyright  2017 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "app_inc.h"

#include "ff.h"
#include "string.h"
#include "tjpgd.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/

uint8_t app_jpg_pixel_buff[LCD_WIDTH*LCD_HEIGHT*2]; /* RGB565. */

#define APP_TJPGDEC_WORKBUFF_SIZE  3100u
uint8_t app_tjpgdec_workbuff[APP_TJPGDEC_WORKBUFF_SIZE];


/*******************************************************************************
 * Code
 ******************************************************************************/


/* User defined device identifier */
typedef struct
{
    FILE *fp;          /* File pointer for input function */
    uint8_t *fbuf;     /* Pointer to the frame buffer for output function */
    uint16_t wfbuf;    /* Width of the frame buffer [pix] */
} IODEV;

uint16_t tjd_input (
	JDEC* jd,		/* Decoder object */
	uint8_t* buff,	/* Pointer to the read buffer (NULL:skip) */
	uint16_t nd		/* Number of bytes to read/skip from input stream */
)
{
	UINT rb;
	FIL *fil = (FIL*)jd->device;	/* Input stream of this session */


	if (buff) {	/* Read nd bytes from the input strem */
		f_read(fil, buff, nd, &rb);
		return rb;	/* Returns number of bytes could be read */

	} else {	/* Skip nd bytes on the input stream */
		return (f_lseek(fil, f_tell(fil) + nd) == FR_OK) ? nd : 0;
	}
}

uint16_t tjd_output (
	JDEC* jd,		/* Decoder object */
	void* bitmap,	/* Bitmap data to be output */
	JRECT* rect		/* Rectangular region to output */
)
{
	jd = jd;	/* Suppress warning (device identifier is not needed) */

	/* Check user interrupt at left end */
	//if (!rect->left && __kbhit()) return 0;	/* Abort decompression */

	/* Put the rectangular into the display */
	//disp_blt(rect->left, rect->right, rect->top, rect->bottom, (uint16_t*)bitmap);

    if (rect->left == 0)
    {
        printf("\r%lu%%", (rect->top << jd->scale) * 100UL / jd->height);
    }

    /* 将解码信息保存在缓冲区中. */

    lcd_fill_rect2(rect->left,//uint16_t hwXpos,  //specify x position.
                   rect->top, //uint16_t hwYpos,  //specify y position.
                   rect->right - rect->left +1,//uint16_t hwWidth, //specify the width of the rectangle.
                   rect->bottom - rect->top +1, //uint16_t hwHeight, //specify the height of the rectangle.
                   bitmap//uint16_t *pixels)  //specify the pixel colors into rectangle.
                   );
	return 1;	/* Continue decompression */
}

FRESULT fs_load_jpg(char *fullpath, uint8_t scale)
{
    FRESULT err;
    FIL   ff_file;        /* File object */
    JDEC  jd_obj;		/* Decoder object (124 bytes) */
	JRESULT rc;
    //uint8_t scale; /* 缩放尺寸. */

    /* open the file. */
    err = f_open(&ff_file, fullpath, FA_READ);
    if (err != FR_OK)
    {
        f_close(&ff_file);
        return err;
    }

    printf("open file: %s\r\n", fullpath);

    rc = jd_prepare(&jd_obj,
                    tjd_input,
                    app_tjpgdec_workbuff,
                    APP_TJPGDEC_WORKBUFF_SIZE,
                    &ff_file);
    if (rc == JDR_OK)
    {
        printf("jd_prepare() done.\r\n");
        //scale = 0; /* 缩放倍数为1<<scale.  */
        rc = jd_decomp(&jd_obj, tjd_output, scale);	/* Start to decompress */
        if (rc == JDR_OK)
        {
            printf("\r\njd_decomp() done.\r\n");
        }
        else
        {
            err = FR_INVALID_OBJECT;
        }
    }
    else
    {
        err = FR_INVALID_OBJECT;
    }

    f_close(&ff_file);

    return err;
}


/* EOF. */

